from typing import Optional
from fastapi import APIRouter, Header, Query
from fastapi.responses import JSONResponse
from db.operations import BookOperations, BookSearchQuery, RandomBookOperations
from model.book_model import BookResponse, Book, BookListResponse

# 创建图书相关的子路由
router = APIRouter(
    prefix="/books",
    tags=["books"],
    responses={404: {"description": "Not found"}},
)


@router.get("/", summary="图书管理接口信息")
async def get_books_info():
    """获取图书管理接口信息和使用示例"""
    api_info = {
        "message": "图书管理API接口",
        "endpoints": {
            "GET /api/books/": "获取图书管理接口信息",
            "GET /api/books/get": "获取指定图书详情",
            "GET /api/books/search": "搜索图书（支持关键字和高级筛选）",
            "GET /api/books/random": "随机获取图书列表",
        },
        "examples": {
            "获取图书详情": {
                "url": "/api/books/get?book_id=123",
                "method": "GET",
                "description": "获取图书ID为123的图书详情",
            },
            "关键字搜索": {
                "url": "/api/books/search?q=python&page=1&limit=10",
                "method": "GET",
                "description": "搜索包含'python'关键字的图书",
            },
            "高级搜索": {
                "url": "/api/books/search?q=编程&min_rating=7&sort_by=rating&sort_order=desc",
                "method": "GET",
                "description": "高级搜索：关键字'编程'，最低评分7分，按评分降序排列",
            },
            "价格筛选": {
                "url": "/api/books/search?min_price=10&max_price=100",
                "method": "GET",
                "description": "筛选价格在10-100元之间的图书",
            },
            "分类筛选": {
                "url": "/api/books/search?main_category=计算机&min_rating=8&page=1&limit=20",
                "method": "GET",
                "description": "筛选计算机类别且评分8分以上的图书",
            },
            "高级搜索示例": {
                "url": "/api/books/search?q=大模型&main_cat=计算机&sub_cat=人工智能&min_rating=7.5&max_rating=10&min_rating_count=10&max_rating_count=100000&min_reading_count=50&max_reading_count=20000&min_price=-1&max_price=200&sort_by=rating&sort_order=desc&page=1&limit=20",
                "method": "GET",
                "description": "高级搜索示例：搜索大模型相关图书，主分类计算机，子分类人工智能，评分最低7.5，评分最高10，评分人数最少10人，最多100000人，在线阅读人数最少50人，最多20000人，价格从-1到200元，按评分降序排列，第一页，每页20本图书",
            },
            "随机获取图书": {
                "url": "/api/books/random?limit=20",
                "method": "GET",
                "description": "随机获取20本图书，包含热门、高分和随机书籍",
            },
        },
    }
    return JSONResponse(status_code=200, content=api_info)


@router.get("/get", summary="获取指定图书详情数据")
async def get_book(
    book_id: int = Query(..., description="图书ID"),
    authorization: Optional[str] = Header(None, description="Bearer token"),
):
    # 去除Bearer前缀
    authorization = authorization.replace("Bearer ", "", 1) if authorization else None
    """获取指定图书详情"""
    book_ops = BookOperations()
    # 查询book_id对应的图书信息
    book_details = await book_ops.batch_query_books_with_categories([book_id])
    results = book_details[0] if book_details else {}
    if not results:
        return JSONResponse(
            status_code=404,
            content=BookResponse(
                message="图书未找到",
                book_data=None,
            ).model_dump(),
        )

    return JSONResponse(
        status_code=200,
        content=BookResponse(
            message="查询成功",
            book_data=Book(**results).model_dump(),
        ).model_dump(),
    )


@router.get("/search", summary="搜索图书（支持高级筛选）")
async def search_books(
    q: str = Query(..., description="搜索关键字"),
    main_cat: Optional[str] = Query(None, description="主分类"),
    sub_cat: Optional[str] = Query(None, description="子分类"),
    min_rating: Optional[float] = Query(
        0, ge=0, le=10, description="最小评分，范围0-10"
    ),
    max_rating: Optional[float] = Query(
        10, ge=0, le=10, description="最大评分，范围0-10"
    ),
    min_rating_count: Optional[int] = Query(0, ge=0, description="最小评分人数，默认0"),
    max_rating_count: Optional[int] = Query(
        None, ge=0, description="最大评分人数，默认不限制"
    ),
    min_reading_count: Optional[int] = Query(
        0, ge=0, description="最小在线阅读人数，默认0"
    ),
    max_reading_count: Optional[int] = Query(
        None, ge=0, description="最大在线阅读人数，默认不限制"
    ),
    min_price: Optional[float] = Query(
        -1, ge=-1, description="最小价格，支持-1到正数范围"
    ),
    max_price: Optional[float] = Query(None, ge=0, description="最大价格，默认不限制"),
    sort_by: Optional[str] = Query(
        "rating_count",
        description="排序方式：'rating'（评分）、'rating_count'（评分人数）、'reading_count'（阅读量）、'price'（价格）、'publish_time'（出版时间）、'title'（标题）",
    ),
    sort_order: Optional[str] = Query(
        "desc", description="排序顺序：'asc'（升序）、'desc'（降序）"
    ),
    page: int = Query(1, ge=1, description="页码，从1开始"),
    limit: int = Query(10, ge=1, le=50, description="每页数量，最大50"),
):
    """
    使用关键字搜索图书，支持在标题、作者、简介中搜索
    支持高级筛选：分类、评分、阅读量、价格等
    支持分页和排序功能
    """
    try:
        search_query = BookSearchQuery()
        total, books_list = await search_query.search_books(
            keyword=q,
            main_category=main_cat,
            sub_category=sub_cat,
            min_rating=min_rating,
            max_rating=max_rating,
            min_rating_count=min_rating_count,
            max_rating_count=max_rating_count,
            min_reading_count=min_reading_count,
            max_reading_count=max_reading_count,
            min_price=min_price,
            max_price=max_price,
            sort_by=sort_by,
            sort_order=sort_order,
            page=page,
            limit=limit,
        )

        books_list = [Book(**book) for book in books_list]

        # 构建响应消息
        if q and q.strip():
            message = f"搜索关键字 '{q}' 完成"
        else:
            message = "图书筛选完成"

        return JSONResponse(
            status_code=200,
            content=BookListResponse(
                message=message,
                books_list=books_list,
                total=total,
                page=page,
                limit=limit,
            ).model_dump(),
        )

    except Exception as e:
        return JSONResponse(
            status_code=500,
            content=BookListResponse(
                message=f"搜索失败: {str(e)}",
                books_list=[],
                total=0,
                page=page,
                limit=limit,
            ).model_dump(),
        )


@router.get("/random", summary="随机获取图书列表")
async def get_random_books(
    limit: int = Query(10, ge=1, le=100, description="获取图书数量，最大100本"),
    hot_ratio: float = Query(0.1, ge=0, le=1, description="热门书籍占比，默认10%"),
    high_rating_ratio: float = Query(
        0.1, ge=0, le=1, description="高分书籍占比，默认10%"
    ),
):
    """
    随机获取图书列表，每次访问都返回不同的图书组合

    策略说明：
    - 热门书籍：从阅读量最高的前1000本中随机选择
    - 高分书籍：从评分最高的前1000本中随机选择
    - 随机书籍：从所有书籍中完全随机选择
    - 剩余比例自动分配给随机书籍
    """
    try:
        # 验证比例参数
        random_ratio = 1.0 - hot_ratio - high_rating_ratio
        if random_ratio < 0:
            return JSONResponse(
                status_code=400,
                content=BookListResponse(
                    message="比例参数错误：热门书籍占比 + 高分书籍占比不能超过1.0",
                    books_list=[],
                    total=0,
                    page=1,
                    limit=limit,
                ).model_dump(),
            )

        # 创建随机书籍操作实例
        random_ops = RandomBookOperations()

        # 获取随机书籍列表
        books_list = await random_ops.get_random_books_by_strategy(
            total_count=limit,
            hot_ratio=hot_ratio,
            high_rating_ratio=high_rating_ratio,
            random_ratio=random_ratio,
        )

        # 转换为Book模型对象
        books_list = [Book(**book) for book in books_list]

        return JSONResponse(
            status_code=200,
            content=BookListResponse(
                message=f"获取随机书籍成功",
                books_list=books_list,
                total=limit,
                page=1,
                limit=limit,
            ).model_dump(),
        )

    except Exception as e:
        return JSONResponse(
            status_code=500,
            content=BookListResponse(
                message=f"随机获取失败: {str(e)}",
                books_list=[],
                total=0,
                page=1,
                limit=limit,
            ).model_dump(),
        )
